package edu.isquen.core.form.model;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.beanutils.PropertyUtils;

import org.htmlparser.Attribute;
import org.htmlparser.Tag;
import org.htmlparser.Text;
import org.htmlparser.visitors.NodeVisitor;

import edu.isquen.core.form.model.element.FormField;
import edu.isquen.core.form.model.element.FormTextPart;
import edu.isquen.util.CommUtil;

public class MyHtmlPaserVisitor extends NodeVisitor {

	Form _form;

	public MyHtmlPaserVisitor() {
	}

	public MyHtmlPaserVisitor(Form form) {
		this._form = form;
	}

	@Override
	public void visitEndTag(Tag tag) {
		String text = tag.getPage().getText(tag.getStartPosition(),
				tag.getEndPosition());
		if (text !=null && ("</SELECT>".equals(text.toUpperCase())
				|| "</TEXTAREA>".equals(text.toUpperCase()))) {
			return;
		}

		if (text != null && text.length() > 0) {
			FormTextPart field = new FormTextPart();
			field.setText(text);
			_form.addFormTextPart(field);
		}
	}

	@Override
	public void visitStringNode(Text text) {
		String str = text.getPage().getText(text.getStartPosition(),
				text.getEndPosition());
		if (!(str == null || str.equals("") || str.equals("\n") || str
				.equals("\n\r"))) {
			FormTextPart field = new FormTextPart();
			field.setText(str);
			_form.addFormTextPart(field);
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public void visitTag(Tag tag) {
		try {
			String className = tag.getAttribute("className");
			if (className == null) {
				String str = tag.getPage().getText(tag.getStartPosition(),
						tag.getEndPosition());
				StringBuffer text = new StringBuffer();

				Collection<?> attributes = tag.getAttributesEx();
				text.append("<");
				if (attributes != null && !attributes.isEmpty()) {
					Iterator<?> iterator = attributes.iterator();
					Attribute attr = (Attribute) iterator.next();
					text.append(attr.getName()); // 第一个属性为TagName

					while (iterator.hasNext()) {
						attr = (Attribute) iterator.next();
						if (attr.getName() != null
								&& !attr.getName().equals("")) {
							text.append(" ").append(attr.getName());
							text.append("='").append(attr.getValue()).append(
									"'");
						}
					}
				}
				text.append(">");

				if (str != null && str.length() > 0) {
					FormTextPart field = new FormTextPart();
					field.setText(text.toString());
					_form.addFormTextPart(field);
				}
			} else {
				Class<?> cls = Class.forName(className);
				Object obj=cls.newInstance();
				if(obj instanceof FormField){
					FormField formfield = (FormField) obj;
					if(formfield.getId()==null || formfield.getId().equals("")){
						formfield.setId(CommUtil.getUUID());
					}
					setFormField(formfield,tag.getAttributesEx());
					_form.addFormField(formfield);
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void setFormField(Object obj, List<Attribute> attributes) throws Exception{
		for(int i=0 ; i<attributes.size();i++){
			Attribute attr = (Attribute) attributes.get(i);
			String fieldname = attr.getName();
			String fieldval = attr.getValue();
			
			Collection<Field> fields=getClassAllFields(obj.getClass());
			
			for(Iterator<Field> iter=fields.iterator();iter.hasNext();){
				Field field = iter.next();
				if (field.getName().equalsIgnoreCase(fieldname)) {
					fieldname = field.getName();
					break;
				}
			}
			
			Class<?> type=null;
			try {
				type = PropertyUtils.getPropertyType(obj, fieldname);
			} catch (Exception e) {
				type = null;
			}
			
			if (type == null) {
				if (obj instanceof FormField) {
					FormField field = (FormField) obj;
					field.addOtherProps(fieldname, fieldval);
				}
				continue;
			}
			if (type != null) {
				if (type.equals(Long.TYPE)) { // Long
					PropertyUtils.setSimpleProperty(obj, fieldname, Long.valueOf(fieldval));
					continue;
				} else if (type.equals(Integer.TYPE)) { // Int
					PropertyUtils.setSimpleProperty(obj, fieldname, Integer.valueOf(fieldval));
					continue;
				} else if (type.equals(Short.TYPE)) { // Short
					PropertyUtils.setSimpleProperty(obj, fieldname, Short.valueOf(fieldval));
					continue;
				} else if (type.equals(Double.TYPE)) { // Double
					PropertyUtils.setSimpleProperty(obj, fieldname, new Double(fieldval));
					continue;
				} else if (type.equals(Class.forName("java.lang.String"))) { // String
					fieldval = fieldval != null ? fieldval : "";
					PropertyUtils.setProperty(obj, fieldname, fieldval.trim());
					continue;
				} else if (type.equals(Float.TYPE)) { // Float
					PropertyUtils.setSimpleProperty(obj, fieldname, new Float(fieldval));
					continue;
				}else if (type.equals(Boolean.TYPE)) { // Boolean
					PropertyUtils.setSimpleProperty(obj, fieldname, Boolean.valueOf(fieldval));
					continue;
				}else if (type.equals(Class.forName("java.util.Date"))) { // java.util.Date
					PropertyUtils.setSimpleProperty(obj, fieldname, null);
					continue;
				}
			}
			
		}
	}
	
	public static Collection<Field> getClassAllFields(Class<?> clazz) {
		Collection<Field> rtn = new ArrayList<Field>();
		Class<?> current = clazz;

		while (current != null) {
			Field[] fields = current.getDeclaredFields();
			rtn.addAll(Arrays.asList(fields));

			current = current.getSuperclass();
		}

		return rtn;
	}

	public Form getResult() {
		return _form;
	}

}
